package com.example.bbtreeflutter;
import android.annotation.SuppressLint;
import android.util.Base64;

import java.io.ByteArrayOutputStream;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class AES {

    private static final boolean DBG = true;
    private static final String TAG = AES.class.getSimpleName();

    private static final int MAX_DECRYPT_BLOCK=128;

    /**
     * 加密
     *
     * @param sSrc
     * @return
     * @throws Exception
     */
    @SuppressLint("NewApi")
    public static String Encrypt(String sKey, String sSrc) throws Exception {

        if (sKey == null) {
            return null;
        }
        // 判断Key是否为16位
//        if (sKey.length() != 16) {
//            LOG.e(DBG, TAG, "Key长度不是16位");
//            return null;
//        }
        byte[] raw = sKey.getBytes("utf-8");
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");//"算法/模式/补码方式"
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));

        return Base64.encodeToString(encrypted, Base64.NO_WRAP);//此处使用BASE64做转码功能，同时能起到2次加密的作用。
    }

    /**
     * 解密
     *
     * @param sSrc
     * @return
     * @throws Exception
     */
    @SuppressLint("NewApi")
    public static String Decrypt(String sKey, String sSrc) throws Exception {
        //Fatal Exception: java.lang.OutOfMemoryError
        //java.lang.AbstractStringBuilder.enlargeBuffer
        // log 信息组装在低配置手机可能造成崩溃
//        LOG.i(DBG, TAG, "Encrypt key:" + sKey + "  src:" + sSrc);
        // 判断Key是否正确
        if (sKey == null) {
            return null;
        }
        // 判断Key是否为16位
//        if (sKey.length() != 16) {
//            LOG.e(DBG, TAG, "Key长度不是16位");
//            return null;
//        }

        byte[] raw = sKey.getBytes("utf-8");
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] encrypted1 = Base64.decode(sSrc, Base64.NO_WRAP);//先用base64解密
        byte[] original = cipher.doFinal(encrypted1);
        return new String(original, "utf-8");
    }

    public static byte[] segmentedEncryptedData(String sKey,byte[] encrypted)throws Exception {
        int inputLen = encrypted.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        byte[] raw = sKey.getBytes("utf-8");
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher
                        .doFinal(encrypted, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher
                        .doFinal(encrypted, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }
}